package org.squabble.domain;

import java.io.Serializable;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Version;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.GenericGenerator;

@Entity(name = "article")
@Table(name = "ARTICLE")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Article implements Serializable {

	private static final long serialVersionUID = 6454234207681639781L;

	@Id
	@Column(name="ID")
    @GenericGenerator(name="article_seq", strategy="increment")
    @GeneratedValue(generator="article_seq") 
	protected Long id;

	@Column(name = "TITLE", nullable = false)
	protected String title;

	@Column(name = "BYLINE")
	protected String byline;

	@Column(name = "CONTENT", nullable = false, length = 4000)
	protected String content;

	@Column(name = "SOURCE_DATE")
	protected Date sourceDate;

	@Column(name = "UPDATE_DATE")
	protected Date updateDate;

	@Column(name = "DISPLAY_DATE")
	protected Date displayDate;

	@Column(name = "REPLYABLE")
	protected boolean replyable;

	@Column(name = "ANNOUNCEMENT")
	protected boolean announcement;

	@Column(name = "DELETED")
	protected boolean deleted;

	@ManyToOne
	@JoinColumn(name = "OWNER_ID")
	protected Account owner;

	@ManyToOne
	@JoinColumn(name = "WRITER_ID")
	protected Account writer;

	@OneToMany
	@JoinColumn(name = "ARTICLE_ID")
	@OrderBy("id")
	protected Set<Comment> comments = new LinkedHashSet<Comment>();

	@ManyToMany
	@JoinTable(name = "ARTICLE_TAG", joinColumns = { @JoinColumn(name = "ARTICLE_ID") }, inverseJoinColumns = { @JoinColumn(name = "TAG_ID") })
	@Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE,
			CascadeType.DELETE })
	protected Set<Tag> tags = new LinkedHashSet<Tag>();

	@Version
	protected Long version;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getByline() {
		return byline;
	}

	public void setByline(String byline) {
		this.byline = byline;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public Date getSourceDate() {
		return sourceDate;
	}

	public void setSourceDate(Date sourceDate) {
		this.sourceDate = sourceDate;
	}

	public Date getUpdateDate() {
		return updateDate;
	}

	public void setUpdateDate(Date updateDate) {
		this.updateDate = updateDate;
	}

	public Date getDisplayDate() {
		return displayDate;
	}

	public void setDisplayDate(Date displayDate) {
		this.displayDate = displayDate;
	}

	public boolean isReplyable() {
		return replyable;
	}

	public void setReplyable(boolean replyable) {
		this.replyable = replyable;
	}

	public boolean isAnnouncement() {
		return announcement;
	}

	public void setAnnouncement(boolean announcement) {
		this.announcement = announcement;
	}

	public boolean isDeleted() {
		return deleted;
	}

	public void setDeleted(boolean deleted) {
		this.deleted = deleted;
	}

	public Account getOwner() {
		return owner;
	}

	public void setOwner(Account owner) {
		this.owner = owner;
	}

	public Account getWriter() {
		return writer;
	}

	public void setWriter(Account writer) {
		this.writer = writer;
	}

	public Set<Comment> getRemarks() {
		return comments;
	}

	public void setRemarks(Set<Comment> comments) {
		this.comments = comments;
	}

	public Set<Tag> getTags() {
		return tags;
	}

	public void setTags(Set<Tag> tags) {
		this.tags = tags;
	}

	public Long getVersion() {
		return version;
	}

	public void setVersion(Long version) {
		this.version = version;
	}

	public String getPreviewContent() {
		String tmp = this.getContent();
		if (tmp.indexOf("<hr />") > -1) {
			tmp = tmp.substring(0, tmp.indexOf("<hr />"));
		}
		return tmp;
	}

}
